<style lang="scss">
    .rule-list {
        background-color: #f0f0f0;
        padding: 10px 10px 56px 10px;
        border-radius: 12px;
        position: relative;

        &__create-btn {
            position: absolute;
            right: 10px;
            bottom: 10px;
        }

        &__item {
            position: relative;
            min-height: 40px;
            border-radius: 12px;
            background-color: #fff;
            padding: 10px;
            margin-top: 16px;
            &:first-child {
                margin-top: 0;
            }

            &__title {
                font-size: 18px;
                color: rgba(0,0,0,.75);
            }

            &__row {
                margin-top: 10px;
                &:first-child {
                    margin-top: 0;
                }
            }

            &__del-btn {
                position: absolute;
                top: 10px;
                right: 10px;
            }
        }
    }
</style>

<script>
// import { availableMembers, patrolPlans } from '@/api/watchman'
import WeeksSelector from './weeksSelector.vue'

export const WeekdaysMap = {
  Monday: { label: '一', value: 1 },
  Tuesday: { label: '二', value: 2 },
  Wednesday: { label: '三', value: 3 },
  Thursday: { label: '四', value: 4 },
  Friday: { label: '五', value: 5 },
  Saturday: { label: '六', value: 6 },
  Sunday: { label: '日', value: 0 }
}

export default {
  components: {
    WeeksSelector
  },
  props: {
    value: {
      type: Object,
      required: true,
      default() {
        return null
      }
    },
    init: {
      type: Boolean,
      default: true
    },
    members: {
      type: Array,
      defualt() {
        return []
      }
    },
    plans: {
      type: Array,
      defualt() {
        return []
      }
    },
    particularDates: {
      type: Array,
      defualt() {
        return []
      }
    },
    fetchMembersFn: {
      type: Function,
      defualt: function() {}
    },
    fetchPatrolPlansFn: {
      type: Function,
      defualt: function() {}
    },
    fetchParticularDatesFn: {
      type: Function,
      defualt: function() {}
    },
    disabled: {
      type: Boolean,
      default: false
    },
    colSize: {
      type: Number,
      default: 23
    },
    loading: {
      type: Boolean,
      default: false
    },
    showCreateRuleBtn: {
      type: Boolean,
      default: true
    },
    showRemoveRuleBtn: {
      type: Boolean,
      default: true
    }
  },
  data() {
    return {
      // form: {
      //     groupName: '',
      //     membersSelected: [],
      //     particularDatesSelected:[],
      //     isIgnoreLegalHolidays: false,
      //     // [{ patrolPlan:{},days:[{key,label,value}] }]
      //     rules: [],
      // },

      ruleForm: {
        patrolPlanSelected: null,
        weekdaysSelected: []
      },

      // availableMembers: [],
      // patrolPlans: [],

      loadingStatuses: {
        isFetchPatrolPlans: false,
        isFetchAvailableMembers: false,
        isFetchParticularDates: false
      },

      createRuleDialog: {
        visible: false
      },

      debounceFns: {
        fetchAvailableMembers: this.debounce(
          this.fetchAvailableMembers,
          500,
          false
        ),
        fetchPatrolPlans: this.debounce(
          this.fetchPatrolPlans,
          500,
          false
        ),
        fetchParticularDates: this.debounce(
          this.fetchParticularDates,
          500,
          false
        )
      },

      weekdaysMap: WeekdaysMap,

      formRules: {
        groupName: [
          { type: 'string', required: true, message: '请输入组名', trigger: ['change', 'blur'] }
        ],
        membersSelected: [
          { type: 'array', required: true, message: '请选择小组成员', trigger: ['change', 'blur'] },
          { type: 'array', required: true, min: 1, message: '至少选择一个小组成员', trigger: ['change', 'blur'] }
        ],
        isIgnoreLegalHolidays: [
          { type: 'boolean', required: false, message: '请选择是否跳过节假日', trigger: 'change' }
        ],
        rules: [
          { type: 'array', required: true, min: 1, message: '至少添加一个规则', trigger: ['change', 'blur'] }
        ]
      },

      ruleFormRules: {
        patrolPlanSelected: [
          { type: 'number', required: true, message: '请选择班次', trigger: ['change', 'blur'] }
        ],
        weekdaysSelected: [
          { type: 'array', required: true, message: '请选择日期', trigger: ['change', 'blur'] },
          { type: 'array', required: true, min: 1, message: '至少选择一天', trigger: ['change', 'blur'] }
        ]
      }
    }
  },
  computed: {
    form: {
      get() {
        return this.value
      },
      set(form) {
        this.$emit('input', form)
      }
    },
    availableUsersFormatted() {
      // const availableMembers = this.members ?? this.availableMembers
      const availableMembers = this.members

      return availableMembers.map(member => {
        const { id, username, phone } = member
        return {
          label: `${username}-${phone}`,
          value: id
        }
      })
    },
    patrolPlansFormatted() {
      // const patrolPlans = this.plans ?? this.patrolPlans
      const patrolPlans = this.plans
      return patrolPlans.map(plan => {
        const { name, id } = plan
        return {
          label: name,
          value: id
        }
      })
    },
    particularDatesFormatted() {
      return this.particularDates?.map(item => {
        return {
          label: item.date,
          value: item.id
        }
      }) ?? []
    },
    rulesFormatted() {
      return this.form.rules.map((rule, index) => {
        const { patrolPlan, days } = rule

        const key = days
          .map(day => day.value)
          .sort()
          .join('')
        return {
          key,
          label: `第${index + 1}条规则`,
          patrolPlan,
          days
        }
      })
    },
    availableWeekdays() {
      const occupied = []

      for (const rule of this.form.rules) {
        for (const day of rule.days) {
          occupied.push(day.key)
        }
      }

      const weekdays = Object.keys(WeekdaysMap)
      return weekdays.filter(day => occupied.indexOf(day) === -1)
    }
  },
  created() {
    this.initData()
  },
  methods: {
    validate() {
      return new Promise((resolve, reject) => {
                this.$refs?.form.validate(flag => {
                  resolve(flag)
                })
      })
    },
    showCreateRuleDialog() {
      if (this.availableWeekdays.length <= 0) {
        this.$message.warning('所有日期已排满')
        return
      }

      this.createRuleDialog.visible = true
    },
    closeCreateRuleDialog() {
      this.createRuleDialog.visible = false
    },
    resetForm() {
            // this.form = {
            //     groupName:'',
            //     membersSelected:[],
            //     isIgnoreLegalHolidays:false,
            //     rules:[]
            // }
            this.$refs?.form.resetFields()
    },
    resetRuleForm() {
      this.ruleForm.patrolPlanSelected = null
      this.ruleForm.weekdaysSelected = []
    },
    saveRule() {
            this.$refs?.ruleForm.validate((valid) => {
              if (!valid) return
              this.form.rules.push({
                patrolPlan: this.plans.find(plan => plan.id === this.ruleForm.patrolPlanSelected),
                days: this.ruleForm.weekdaysSelected.map(item => {
                  const { key, label, value } = item
                  return { key, label, value }
                })
              })

              this.closeCreateRuleDialog()
              this.resetRuleForm()
            })
    },
    delRule(index) {
      this.form.rules.splice(index, 1)
    },
    async withErrorHandler(fn, handler, ...args) {
      try {
        if (!(fn instanceof Function)) return

        if (fn.constructor.name === 'AsyncFunction') { await fn() }

        const result = fn()
        if (result instanceof Promise) { await result() }
      } catch (error) {
                handler?.(error)
      }
    },
    async fetchAvailableMembers(keyword) {
      try {
        this.loadingStatuses.isFetchAvailableMembers = true
        await this.fetchMembersFn?.(keyword)
        this.loadingStatuses.isFetchAvailableMembers = false
      } catch (error) {
        this.loadingStatuses.isFetchAvailableMembers = false
      }
    },
    async fetchPatrolPlans(keyword) {
      try {
        this.loadingStatuses.isFetchPatrolPlans = true
        await this.fetchPatrolPlansFn?.(keyword)
        this.loadingStatuses.isFetchPatrolPlans = false
      } catch (error) {
        this.loadingStatuses.isFetchPatrolPlans = false
      }
    },
    async fetchParticularDates(keyword) {
      try {
        this.loadingStatuses.isFetchParticularDates = true
        await this.fetchParticularDatesFn?.(keyword)
        this.loadingStatuses.isFetchParticularDates = false
      } catch (error) {
        this.loadingStatuses.isFetchParticularDates = false
      }
    },
    debounce(fn, delay) {
      let timeout
      return function() {
        clearTimeout(timeout)
        timeout = setTimeout(() => fn.apply(this, arguments), delay)
      }
    },
    async loadData() {
      const result = await Promise.allSettled([
        this.fetchAvailableMembers(),
        this.fetchPatrolPlans(),
        this.fetchParticularDates()
      ])

      const failTasks = result.filter(task => task.status === 'rejected')
      if (failTasks.length <= 0) return

      throw failTasks.at(0).reason
    },
    async initData() {
      try {
        if (!this.init) return
        await this.loadData()
      } catch (error) {
        console.log(error)
        this.$message.error('初始化数据失败')
      }
    }
  }
}
</script>

<template>
  <div>
    <el-row>
      <el-col :span="colSize">
        <el-form
          ref="form"
          v-loading="loading"
          label-width="100px"
          :rules="formRules"
          :model="form"
          :disabled="disabled"
        >

          <el-form-item label="小组名称" prop="groupName">
            <el-input v-model="form.groupName" placeholder="请输入小组名称" />
          </el-form-item>

          <el-form-item label="小组成员" prop="membersSelected">
            <el-select
              v-model="form.membersSelected"
              filterable
              multiple
              remote
              :loading="loadingStatuses.isFetchAvailableMembers"
              :remote-method="debounceFns.fetchAvailableMembers"
              placeholder="请选择"
              style="width: 100%;"
            >
              <el-option
                v-for="user in availableUsersFormatted"
                :key="user.value"
                :label="user.label"
                :value="user.value"
              />
            </el-select>
          </el-form-item>

          <el-form-item label="特殊日期" prop="particularDatesSelected">
            <el-select
              v-model="form.particularDatesSelected"
              filterable
              multiple
              remote
              :loading="loadingStatuses.isFetchParticularDates"
              :remote-method="debounceFns.fetchParticularDates"
              placeholder="请选择特殊日期"
              style="width: 100%;"
            >
              <el-option
                v-for="date in particularDatesFormatted"
                :key="date.value"
                :label="date.label"
                :value="date.value"
              />
            </el-select>
          </el-form-item>

          <el-form-item label="跳过节假日" prop="isIgnoreLegalHolidays">
            <el-switch v-model="form.isIgnoreLegalHolidays" />
          </el-form-item>

          <el-form-item label="规则列表" prop="rules">
            <el-row>
              <el-col :span="24">
                <div class="rule-list">
                  <el-empty v-if="rulesFormatted.length <= 0" description="暂无规则" :image-size="80" />
                  <template v-else>
                    <div
                      v-for="(rule, index) in rulesFormatted"
                      :key="rule.key"
                      class="rule-list__item"
                    >
                      <div class="rule-list__item__row rule-list__item__title">
                        {{ rule.label }}
                      </div>

                      <div class="rule-list__item__row">
                        <el-input disabled :value="rule.patrolPlan.name" placeholder="小组名称" />
                      </div>

                      <div class="rule-list__item__row">
                        <WeeksSelector
                          :value="rule.days"
                          disabled
                        />
                      </div>

                      <div v-if="showRemoveRuleBtn" class="rule-list__item__del-btn">
                        <el-button circle size="mini" icon="el-icon-close" @click="delRule(index)" />
                      </div>
                    </div>
                  </template>

                  <div v-if="showCreateRuleBtn" class="rule-list__create-btn">
                    <el-button icon="el-icon-plus" @click="showCreateRuleDialog">添加规则</el-button>
                  </div>
                </div>
              </el-col>
            </el-row>
          </el-form-item>

          <el-form-item>
            <slot name="actions" />
          </el-form-item>
        </el-form>
      </el-col>
    </el-row>

    <el-dialog :close-on-click-modal="false"
      :visible.sync="createRuleDialog.visible"
      :before-close="closeCreateRuleDialog"
      title="添加规则"
      width="35%"
      destroy-on-close
      append-to-body
    >
      <div
        v-loading="false"
        class="body"
      >
        <el-row>
          <el-col :span="23">
            <el-form
              ref="ruleForm"
              label-width="80px"
              :rules="ruleFormRules"
              :model="ruleForm"
            >

              <el-form-item label="添加规则" prop="patrolPlanSelected">
                <el-select
                  v-model="ruleForm.patrolPlanSelected"
                  placeholder="请选择班次"
                  style="width: 100%;"
                  filterable
                  remote
                  :loading="loadingStatuses.isFetchPatrolPlans"
                  :remote-method="debounceFns.fetchPatrolPlans"
                >
                  <el-option
                    v-for="user in patrolPlansFormatted"
                    :key="user.value"
                    :label="user.label"
                    :value="user.value"
                  />
                </el-select>
              </el-form-item>

              <el-form-item label="选择日期" prop="weekdaysSelected">
                <WeeksSelector
                  v-model="ruleForm.weekdaysSelected"
                  :available-weekdays="availableWeekdays"
                />
              </el-form-item>
            </el-form>
          </el-col>
        </el-row>
      </div>

      <div slot="footer">
        <el-button type="primary" @click="saveRule">
          添加
        </el-button>

        <el-button @click="closeCreateRuleDialog">
          取消
        </el-button>
      </div>
    </el-dialog>
  </div>
</template>
